home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ROADS15.ARJ / INITROAD.C < prev    next >
C/C++ Source or Header  |  1993-12-15  |  15KB  |  468 lines

  1. #define INITROAD_C
  2.  
  3. #include <stdlib.h>
  4. #include <time.h>
  5. #include <fastgraf.h>
  6. #include "roads.h"
  7. #include "tiles.h"
  8.  
  9. extern int far *topography;      /* BACKGROUND TILE LIST (ARRAY) */
  10. extern int far *terrain;      /* FOREGROUND TILE LIST (ARRAY) */
  11.  
  12. /* FOR AI - NUMBER OF ROADS TO PLACE ON SCREEN */
  13. #define MAX_ROADS ((WORLD_WIDTH+WORLD_HEIGHT)/2)
  14. #define MIN_ROADS ((WORLD_WIDTH+WORLD_HEIGHT)/8)
  15. #define CHANCE_CROSSROAD 75 /* 3/4 CHANCE OF A CROSSROAD VS T */
  16.  
  17. /* DIRECTIONS */
  18. #define NUM_DIRECTIONS  4
  19. #define FIRST_DIRECTION 1
  20.  
  21. #define DIRECTION_UP    1
  22. #define DIRECTION_DOWN  2
  23. #define DIRECTION_LEFT  3
  24. #define DIRECTION_RIGHT 4
  25.  
  26. #define ROAD_LEADERS 12 /* USED IN CREATE_ROADS */
  27.  
  28. /*
  29.  *
  30.  * Randomly creates roads and places them in the foreground tile list.
  31.  * This function overwrites other non-road foreground tiles.
  32.  * (To prevent this, call this function first.)
  33.  *
  34.  */
  35. void create_roads (void)
  36. {
  37.     int entry, keepgoing=TRUE, direction, chance;
  38.     int x,y,nextx,nexty; /* LOCATION OF CURRENTLY PLACED ROAD TILE */
  39.     int roads_left; /* NUMBER OF COMPLETE ROADS LEFT TO PLACE */
  40.     int failed_roads=0;
  41.     int current_tile;
  42.  
  43.         /* ROADS ARE PICKED FROM THESE LISTS -- INCREASE ROAD_LEADERS  */
  44.         /* AND ADD ROAD TILES TO THESE LISTS TO INCREASE CHANCE OF     */
  45.         /* SPECIFIED ROADS BEING PLACED                                */
  46.     int roads_to_right [ROAD_LEADERS] = { ROAD_H, ROAD_H, ROAD_UR, ROAD_DR,
  47.                                           ROAD_H, ROAD_H, ROAD_H, ROAD_H,
  48.                                           ROAD_H, ROAD_H, ROAD_H, ROAD_H,  };
  49.     int roads_to_left  [ROAD_LEADERS] = { ROAD_H, ROAD_H, ROAD_UL, ROAD_DL,
  50.                                           ROAD_H, ROAD_H, ROAD_H, ROAD_H,
  51.                                           ROAD_H, ROAD_H, ROAD_H, ROAD_H,  };
  52.     int roads_to_down  [ROAD_LEADERS] = { ROAD_V, ROAD_V, ROAD_UL, ROAD_UR,
  53.                                           ROAD_V, ROAD_V, ROAD_V, ROAD_V,
  54.                                           ROAD_V, ROAD_V, ROAD_V, ROAD_V,  };
  55.     int roads_to_up    [ROAD_LEADERS] = { ROAD_V, ROAD_V, ROAD_DL, ROAD_DR,
  56.                                           ROAD_V, ROAD_V, ROAD_V, ROAD_V,
  57.                                           ROAD_V, ROAD_V, ROAD_V, ROAD_V,  };
  58.  
  59.     roads_left=random (MAX_ROADS-MIN_ROADS)+MIN_ROADS;
  60.  
  61.         /************************************************\
  62.          *     PLACE FIRST TILE AT WORLD SCREEN EDGE    *
  63.         \************************************************/
  64.  
  65.     while (roads_left-- && failed_roads<=MAX_FAILS)
  66.     {
  67.             /* PICK RANDOM ENTRY POINT */
  68.         keepgoing=TRUE;
  69.         entry=random(NUM_DIRECTIONS)+FIRST_DIRECTION;
  70.         switch (entry)
  71.         {
  72. /********/  case DIRECTION_UP: /* TOP ENTRY */
  73.  
  74.             x=random(WORLD_WIDTH); y=0;
  75.             current_tile=terrain[WORLD_TILE(x,y)];
  76.  
  77.             if (!isroad(current_tile))
  78.             {
  79.                 current_tile=terrain[WORLD_TILE(x,y)]=
  80.                     roads_to_up[random(ROAD_LEADERS)];
  81.                 direction=roadexit(current_tile, DIRECTION_DOWN);
  82.                 break;
  83.             }
  84.  
  85.             else
  86.             {
  87.                 roads_left++;
  88.                 failed_roads++;
  89.                 keepgoing=FALSE;
  90.                 break;
  91.             }
  92.  
  93. /********/  case DIRECTION_DOWN: /* BOTTOM ENTRY */
  94.  
  95.             x=random(WORLD_WIDTH); y=WORLD_HEIGHT-1;
  96.             current_tile=terrain[WORLD_TILE(x,y)];
  97.  
  98.             if (!isroad(current_tile))
  99.             {
  100.                 current_tile=terrain[WORLD_TILE(x,y)]=
  101.                     roads_to_down[random(ROAD_LEADERS)];
  102.                 direction=roadexit(current_tile, DIRECTION_UP);
  103.             }
  104.  
  105.             else
  106.             {
  107.                 roads_left++;
  108.                 failed_roads++;
  109.                 keepgoing=FALSE;
  110.             }
  111.             break;
  112.  
  113. /********/  case DIRECTION_LEFT: /* LEFT ENTRY */
  114.  
  115.             x=0; y=random(WORLD_HEIGHT);
  116.             current_tile=terrain[WORLD_TILE(x,y)];
  117.  
  118.             if (!isroad(current_tile))
  119.             {
  120.                 current_tile=terrain[WORLD_TILE(x,y)]=
  121.                     roads_to_left[random(ROAD_LEADERS)];
  122.                 direction=roadexit(current_tile, DIRECTION_RIGHT);
  123.             }
  124.  
  125.             else
  126.             {
  127.                 roads_left++;
  128.                 failed_roads++;
  129.                 keepgoing=FALSE;
  130.             }
  131.             break;
  132.  
  133. /********/  case DIRECTION_RIGHT: /* RIGHT ENTRY */
  134.  
  135.             x=WORLD_WIDTH-1; y=random(WORLD_HEIGHT);
  136.             current_tile=terrain[WORLD_TILE(x,y)];
  137.  
  138.             if (!isroad(current_tile))
  139.             {
  140.                 current_tile=terrain[WORLD_TILE(x,y)]=
  141.                     roads_to_right[random(ROAD_LEADERS)];
  142.                 direction=roadexit(current_tile, DIRECTION_LEFT);
  143.             }
  144.  
  145.             else
  146.             {
  147.                 roads_left++;
  148.                 failed_roads++;
  149.                 keepgoing=FALSE;
  150.             }
  151.             break;
  152.         }
  153.  
  154.         /************************************************\
  155.          * PLACE SUBSEQUENT TILES AWAY FROM ENTRY POINT *
  156.         \************************************************/
  157.  
  158.         while (keepgoing)
  159.         {
  160.             switch (direction)
  161.             {
  162. /********/      case DIRECTION_UP: /* UP */
  163.  
  164.                 if (--y<0)
  165.                 {
  166.                     keepgoing=FALSE;
  167.                     break;
  168.                 }
  169.  
  170.                 current_tile=terrain[WORLD_TILE(x,y)];
  171.                 if (!isroad(current_tile))
  172.                 {
  173.                     current_tile=terrain[WORLD_TILE(x,y)]=
  174.                         roads_to_down[random(ROAD_LEADERS)];
  175.                     direction=roadexit(current_tile, DIRECTION_UP);
  176.                 }
  177.  
  178.                 else /* INTERSECTION OCCURS */
  179.                 {
  180.                     if (random(100)>=CHANCE_CROSSROAD &&
  181.                         terrain[WORLD_TILE(x,y-1)]==EMPTY_TILE)
  182.                     {
  183.                         keepgoing=FALSE;
  184.                         terrain[WORLD_TILE(x,y)]=makeintersection
  185.                             (current_tile, DIRECTION_DOWN);
  186.                     }
  187.  
  188.                     else /* CROSSROAD AND CONTINUE */
  189.                     {
  190.                         terrain[WORLD_TILE(x,y)]=makeintersection
  191.                             (makeintersection(current_tile, DIRECTION_UP),
  192.                             DIRECTION_DOWN); /* ADD BOTH RAMPS */
  193.                     }
  194.                 }
  195.                 break;
  196.  
  197. /********/      case DIRECTION_DOWN:  /* DOWN */
  198.  
  199.                 if (++y>=WORLD_HEIGHT)
  200.                 {
  201.                     keepgoing=FALSE;
  202.                     break;
  203.                 }
  204.  
  205.                 current_tile=terrain[WORLD_TILE(x,y)];
  206.                 if (!isroad(current_tile))
  207.                 {
  208.                     current_tile=terrain[WORLD_TILE(x,y)]=
  209.                         roads_to_up[random(ROAD_LEADERS)];
  210.                     direction=roadexit(current_tile, DIRECTION_DOWN);
  211.                 }
  212.  
  213.                 else /* INTERSECTION OCCURS */
  214.                 {
  215.                     if (random(100)>=CHANCE_CROSSROAD &&
  216.                         terrain[WORLD_TILE(x,y+1)]==EMPTY_TILE)
  217.  
  218.                     {
  219.                         keepgoing=FALSE;
  220.                         terrain[WORLD_TILE(x,y)]=makeintersection
  221.                             (current_tile, DIRECTION_UP);
  222.                     }
  223.  
  224.                     else /* CROSSROAD AND CONTINUE */
  225.                     {
  226.                         terrain[WORLD_TILE(x,y)]=makeintersection
  227.                             (makeintersection(current_tile, DIRECTION_DOWN),
  228.                             DIRECTION_UP); /* ADD BOTH RAMPS */
  229.                     }
  230.                 }
  231.                 break;
  232.  
  233. /********/      case DIRECTION_LEFT: /* LEFT */
  234.  
  235.                 if (--x<0)
  236.                 {
  237.                     keepgoing=FALSE;
  238.                     break;
  239.                 }
  240.  
  241.                 current_tile=terrain[WORLD_TILE(x,y)];
  242.                 if (!isroad(current_tile))
  243.                 {
  244.                     current_tile=terrain[WORLD_TILE(x,y)]=
  245.                         roads_to_right[random(ROAD_LEADERS)];
  246.                     direction=roadexit(current_tile, DIRECTION_LEFT);
  247.                 }
  248.  
  249.                 else /* INTERSECTION OCCURS */
  250.                 {
  251.                     if (random(100)>=CHANCE_CROSSROAD &&
  252.                         terrain[WORLD_TILE(x-1,y)]==EMPTY_TILE)
  253.  
  254.                     {
  255.                         keepgoing=FALSE;
  256.                         terrain[WORLD_TILE(x,y)]=makeintersection
  257.                             (current_tile, DIRECTION_RIGHT);
  258.                     }
  259.  
  260.                     else /* CROSSROAD AND CONTINUE */
  261.                     {
  262.                         terrain[WORLD_TILE(x,y)]=makeintersection
  263.                             (makeintersection(current_tile, DIRECTION_LEFT),
  264.                             DIRECTION_RIGHT); /* ADD BOTH RAMPS */
  265.                     }
  266.                 }
  267.                 break;
  268.  
  269. /********/      case DIRECTION_RIGHT: /* RIGHT */
  270.  
  271.                 if (++x>=WORLD_WIDTH)
  272.                 {
  273.                     keepgoing=FALSE;
  274.                     break;
  275.                 }
  276.  
  277.                 current_tile=terrain[WORLD_TILE(x,y)];
  278.                 if (!isroad(current_tile))
  279.                 {
  280.                     current_tile=terrain[WORLD_TILE(x,y)]=
  281.                         roads_to_left[random(ROAD_LEADERS)];
  282.                     direction=roadexit(current_tile, DIRECTION_RIGHT);
  283.                 }
  284.  
  285.                 else /* INTERSECTION OCCURS */
  286.                 {
  287.                     if (random(100)>=CHANCE_CROSSROAD &&
  288.                         terrain[WORLD_TILE(x+1,y)]==EMPTY_TILE)
  289.  
  290.                     {
  291.                         keepgoing=FALSE;
  292.                         terrain[WORLD_TILE(x,y)]=makeintersection
  293.                             (current_tile, DIRECTION_LEFT);
  294.                     }
  295.  
  296.                     else /* CROSSROAD AND CONTINUE */
  297.                     {
  298.                         terrain[WORLD_TILE(x,y)]=makeintersection
  299.                             (makeintersection(current_tile, DIRECTION_RIGHT),
  300.                             DIRECTION_LEFT); /* ADD BOTH RAMPS */
  301.                     }
  302.                 }
  303.                 break;
  304.             } /* "DIRECTION" HERE */
  305.         } /* STOP "KEEPGOING" HERE */
  306.     }
  307. }
  308.  
  309. /*
  310.  *
  311.  * Returns the unspecified direction in an angled road.
  312.  *
  313.  */
  314. int roadexit (int road, int direction)
  315. {
  316.     switch (direction)
  317.     {
  318.         case DIRECTION_UP: /* up */
  319.         if (road==ROAD_V)  return DIRECTION_UP;
  320.         if (road==ROAD_UL) return DIRECTION_LEFT;
  321.         if (road==ROAD_UR) return DIRECTION_RIGHT;
  322.         break;
  323.  
  324.         case DIRECTION_DOWN: /* down */
  325.         if (road==ROAD_V)  return DIRECTION_DOWN;
  326.         if (road==ROAD_DL) return DIRECTION_LEFT;
  327.         if (road==ROAD_DR) return DIRECTION_RIGHT;
  328.         break;
  329.  
  330.         case DIRECTION_LEFT: /* left */
  331.         if (road==ROAD_DR) return DIRECTION_UP;
  332.         if (road==ROAD_UR) return DIRECTION_DOWN;
  333.         if (road==ROAD_H)  return DIRECTION_LEFT;
  334.         break;
  335.  
  336.         case DIRECTION_RIGHT: /* right */
  337.         if (road==ROAD_DL) return DIRECTION_UP;
  338.         if (road==ROAD_UL) return DIRECTION_DOWN;
  339.         if (road==ROAD_H)  return DIRECTION_RIGHT;
  340.         break;
  341.     }
  342.  
  343.     fg_music ("A$");
  344.     return ERROR_TILE;
  345. }
  346.  
  347. /*
  348.  *
  349.  * Adds a road (ramp) to the specified road, and returns the
  350.  * tile number of what the new road is made of.
  351.  *
  352.  */
  353. int makeintersection (int road, int ramp)
  354. {
  355.     switch (road)
  356.     {
  357.         case ROAD_X:  /* ┼ */
  358.         return ROAD_X;
  359.  
  360.         case ROAD_V:  /* │ */
  361.         if (ramp==DIRECTION_LEFT) return ROAD_TL;
  362.         if (ramp==DIRECTION_RIGHT) return ROAD_TR;
  363.         return ROAD_V;
  364.  
  365.         case ROAD_H:  /* ─ */
  366.         if (ramp==DIRECTION_UP) return ROAD_TU;
  367.         if (ramp==DIRECTION_DOWN) return ROAD_TD;
  368.         return ROAD_H;
  369.  
  370.         case ROAD_UR: /* ┌ */
  371.         if (ramp==DIRECTION_UP) return ROAD_TR;
  372.         if (ramp==DIRECTION_LEFT) return ROAD_TD;
  373.         return ROAD_UR;
  374.  
  375.         case ROAD_UL: /* ┐ */
  376.         if (ramp==DIRECTION_UP) return ROAD_TL;
  377.         if (ramp==DIRECTION_RIGHT) return ROAD_TD;
  378.         return ROAD_UL;
  379.  
  380.         case ROAD_DR: /* └ */
  381.         if (ramp==DIRECTION_DOWN) return ROAD_TR;
  382.         if (ramp==DIRECTION_LEFT) return ROAD_TU;
  383.         return ROAD_DR;
  384.  
  385.         case ROAD_DL: /* ┘ */
  386.         if (ramp==DIRECTION_DOWN) return ROAD_TL;
  387.         if (ramp==DIRECTION_RIGHT) return ROAD_TU;
  388.         return ROAD_DL;
  389.  
  390.         case ROAD_TL: /* ┤ */
  391.         if (ramp==DIRECTION_RIGHT) return ROAD_X;
  392.         return ROAD_TL;
  393.  
  394.         case ROAD_TR: /* ├ */
  395.         if (ramp==DIRECTION_LEFT) return ROAD_X;
  396.         return ROAD_TR;
  397.  
  398.         case ROAD_TU: /* ┴ */
  399.         if (ramp==DIRECTION_DOWN) return ROAD_X;
  400.         return ROAD_TU;
  401.  
  402.         case ROAD_TD: /* ┬ */
  403.         if (ramp==DIRECTION_UP) return ROAD_X;
  404.         return ROAD_TD;
  405.     }
  406.  
  407.     fg_music ("A$");
  408.     return ERROR_TILE;
  409. }
  410.  
  411. /*
  412.     AI USED IN ROAD FUNCTIONS:
  413.     pick random entry point on one of the four sides
  414.     place subsequent tiles with tendency to move from screen
  415.     place subsequent tiles with tendency use V or H pieces if just used
  416.     if hit existing tile, either
  417.     a) cross over road and continue, using X tile
  418.     b) terminate road with a T
  419.     repeat until MAX_ROADS complete
  420. */
  421.  
  422. /*
  423.  *
  424.  * Adds edges to places where grass and dirt meet.
  425.  * Called by init_background() to liven up background display.
  426.  *
  427.  */
  428. void add_dirt_edges (void)
  429. {
  430.     register int x, y;
  431.     int tile;
  432.  
  433.     /* ADD 90 DEGREE EDGES */
  434.     for (y=0; y<WORLD_HEIGHT; y++)
  435.     for (x=0; x<WORLD_WIDTH; x++)
  436.     if (isdirt(topography[WORLD_TILE(x,y)]))
  437.     {
  438.         tile=0; /* ADD UP BINARY TILE NUMBER */
  439.         if (y-1>=0) tile+=isgrass(topography[WORLD_TILE(x,y-1)]);
  440.         if (x+1<WORLD_WIDTH) tile+=isgrass(topography[WORLD_TILE(x+1,y)])*2;
  441.         if (y+1<WORLD_HEIGHT) tile+=isgrass(topography[WORLD_TILE(x,y+1)])*4;
  442.         if (x-1>=0) tile+=isgrass(topography[WORLD_TILE(x-1,y)])*8;
  443.  
  444.         /* CONVERT BINARY TILE NUMBER TO ACTUAL */
  445.         switch (tile)
  446.         {
  447.             case 1:  tile=DIRTEDGE_U;    break;
  448.             case 2:  tile=DIRTEDGE_R;    break;
  449.             case 3:  tile=DIRTEDGE_UR;   break;
  450.             case 4:  tile=DIRTEDGE_D;    break;
  451.             case 5:  tile=DIRTEDGE_UD;   break;
  452.             case 6:  tile=DIRTEDGE_RD;   break;
  453.             case 7:  tile=DIRTEDGE_URD;  break;
  454.             case 8:  tile=DIRTEDGE_L;    break;
  455.             case 9:  tile=DIRTEDGE_UL;   break;
  456.             case 10: tile=DIRTEDGE_RL;   break;
  457.             case 11: tile=DIRTEDGE_URL;  break;
  458.             case 12: tile=DIRTEDGE_DL;   break;
  459.             case 13: tile=DIRTEDGE_UDL;  break;
  460.             case 14: tile=DIRTEDGE_RDL;  break;
  461.             case 15: tile=DIRTEDGE_URDL; break;
  462.             case 0:  tile=topography[WORLD_TILE(x,y)]; break; /* NO CHANGE */
  463.         }
  464.         topography[WORLD_TILE(x,y)]=tile; /* CHANGE TILE */
  465.     }
  466. }
  467.  
  468.